package com.iflytek.uoamp.agent.monitor.timer.monitor;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSON;
import com.iflytek.uoamp.agent.common.util.Constant;
import com.iflytek.uoamp.agent.core.sender.monitorsender.monitorinterface.IItem;
import com.iflytek.uoamp.agent.core.sender.monitorsender.requestObj.*;
import com.iflytek.uoamp.agent.monitor.job.ServerMonitorJob;
import com.iflytek.uoamp.agent.monitor.job.ShellExecutor;
import com.iflytek.uoamp.agent.monitor.mcagent.MCAgentConfig;
import com.iflytek.uoamp.agent.monitor.mcagent.MCAgentMain;

public class OnceMonitorListener implements Runnable {

	@Override
	public void run() {
		try {
			if(MCAgentMain.getSenderClient().getConfig().isUseHttp()){
				dealMonitor4Http();
			}else{
				dealMonitor4Thrift();
			}
		} catch (Exception e) {
			Logger.getRootLogger().error("Once Monitor thread throws except: "  + ExceptionUtils.getMessage(e));
		}
	}

	private void dealMonitor4Thrift() {
		Object result = MCAgentMain.getSenderClient().sendBySafe(getOnceMonitorRequest());
		if (!(result instanceof List)) {
			return;
		}
		@SuppressWarnings("unchecked")
		List<MonitorItemConfig> configs = (List<MonitorItemConfig>) result;
		
		if (configs.isEmpty()) {
			Logger.getRootLogger().info("No Once Monitor Scheduler to do!!!");
			return;
		}
		
		List<MonitorItemResult> monitorRlts = dealOnceMonitor(configs);
		SendResponse response =  (SendResponse)MCAgentMain.getSenderClient().sendBatchBySafe(convertToIITem(monitorRlts));	
		if (response == null || SendResponse.RESPONSESTATUS.ERROR.equals(response.getStatus())) {
			Logger.getRootLogger().error("once monitor send result fail");
		}
		
		for (MonitorItemResult rlt : monitorRlts) {
			Logger.getRootLogger().info("once monitor result: " + rlt.getRltDes());
		}
	}
	
	private void dealMonitor4Http() {
		Object result = MCAgentMain.getSenderClient().sendByHttp(getOnceMonitorRequest());
		@SuppressWarnings("rawtypes")
		List list = JSON.parseObject(result.toString(), List.class);
		List<MonitorItemConfig> itemsConfig = new LinkedList<MonitorItemConfig>() ;
		for(Object cur:list){
			itemsConfig.add(JSON.parseObject(cur.toString(), MonitorItemConfig.class));
		}
		
		if (itemsConfig.isEmpty()) {
			return;
		}
		List<MonitorItemResult> monitorRlts = dealOnceMonitor(itemsConfig);
		SendResponse response =  JSON.parseObject(MCAgentMain.getSenderClient().sendBatchByHttp(convertToIITem(monitorRlts)).toString(), SendResponse.class);
		if (response == null || SendResponse.RESPONSESTATUS.ERROR.equals(response.getStatus())) {
			Logger.getRootLogger().error("once monitor send result fail");
		}
		
		Logger.getRootLogger().info("finish once monitor: ");
		for (MonitorItemResult rlt : monitorRlts) {
			Logger.getRootLogger().info("no send result: " + rlt.getRltDes());
		}
	}
	
	private List<MonitorItemResult> dealOnceMonitor(List<MonitorItemConfig> itemsConfig) {
		List<MonitorItemResult> monitorResults = new ArrayList<MonitorItemResult>();
		
		for (MonitorItemConfig config : itemsConfig) {
			ShellExecutor shellExrcutor = new ShellExecutor(config);
			MonitorItemResult result = shellExrcutor.check();
//			if (null != result) {
				Logger.getRootLogger().info("once monitor getMonitorResults Service " + config.getServerDesc() + " return_code:" + result.getReturnCode() + " output: " + result.getOutput());
				monitorResults.add(result);
//			} else {
//				Logger.getRootLogger().error("once monitor getMonitorResults Service " + config.getServerDesc() + " return monitor result is null and command is "+shellExrcutor.getCommand());
//				monitorResults.add(ServerMonitorJob.createErrorResult(config));
//			}
		}
		return monitorResults;
	}
	
	private static List<IItem> convertToIITem(List<MonitorItemResult> monitorRlts) {
		List<IItem> sendObjs = new LinkedList<IItem>();
		
		for(MonitorItemResult cur:monitorRlts){
			cur.getHeader().put("configs", "");
			sendObjs.add(cur);
		}
		
		return sendObjs;
	}
	private static MonitorPluginType getOnceMonitorRequest() {
		if (ONCE_MONITOR_REQUEST == null) {
			MonitorPluginType request = new MonitorPluginType(MCAgentConfig.getInstance().getMonitoredPointIp(),Constant.ONCEMONITORREQTYPE, new ArrayList<String>());
			ONCE_MONITOR_REQUEST = request;
		}
		
		return ONCE_MONITOR_REQUEST;
	}
	private static MonitorPluginType ONCE_MONITOR_REQUEST = null;
}
